#include "clienttransfer.h"
#include "timestamp.h"

ClientTransfer::ClientTransfer()
{
    this->m_info_sock.bind(DEFAULT_CLIENT_INFO_PORT);
    this->m_sync_sock.bind(DEFAULT_CLIENT_SYNC_PORT);
    this->m_data_sock.bind(DEFAULT_CLIENT_DATA_PORT);
    this->m_request.resize(sizeof(normal_request_t));
    QObject::connect(&this->m_info_sock, SIGNAL(readyRead()), this, SLOT(recvInfoResponse()));
    QObject::connect(&this->m_sync_sock, SIGNAL(readyRead()), this, SLOT(recvSyncResponse()));
    QObject::connect(&this->m_data_sock, SIGNAL(readyRead()), this, SLOT(recvDataResponse()));
    QObject::connect(&this->m_timer, SIGNAL(timeout()), this, SLOT(timerRequest()));
    this->m_server_set = false;
    this->m_timer.stop();
}


void ClientTransfer::recvInfoResponse(){
    QByteArray datagram;
    QHostAddress sender;
    quint16 senderPort;
    datagram.resize(this->m_info_sock.pendingDatagramSize());
    this->m_info_sock.readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
    processDatagram(datagram);
}

void ClientTransfer::recvSyncResponse(){
    QByteArray datagram;
    QHostAddress sender;
    quint16 senderPort;
    datagram.resize(this->m_sync_sock.pendingDatagramSize());
    this->m_sync_sock.readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
    processDatagram(datagram);
}

void ClientTransfer::recvDataResponse(){
    QByteArray datagram;
    QHostAddress sender;
    quint16 senderPort;
    datagram.resize(this->m_data_sock.pendingDatagramSize());
    this->m_data_sock.readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
    processDatagram(datagram);
}

void ClientTransfer::timerRequest(){
    QByteArray request;
    static int count = 0;
    request.resize(sizeof(normal_request_t));
    requestInfo(request.data())->type = SYNC_REQUEST;
    requestInfo(request.data())->action = GET;
    setRequestField(request.data(), SYNC_TIME, (int)TimeStamp::now()->toInt());
    setRequestField(request.data(), SYNC_COUNT, count++);
    packRequest(request);
    sendSyncRequest(request);
}

void ClientTransfer::packRequest(QByteArray& request){
    requestInfo(request.data())->magic = REQUEST_MAGIC;
    requestInfo(request.data())->timestamp = TimeStamp::now()->toInt();
}

void ClientTransfer::sendSyncRequest(QByteArray request){
    this->m_sync_sock.writeDatagram(request, this->m_server_addr, this->m_server_sync_port);
}


void ClientTransfer::sendInfoRequest(QByteArray request){
    this->m_info_sock.writeDatagram(request, this->m_server_addr, this->m_server_info_port);
}

void ClientTransfer::sendDataRequest(QByteArray request){
    this->m_data_sock.writeDatagram(request, this->m_server_addr, this->m_server_data_port);
}



void ClientTransfer::processDatagram(QByteArray datagram){
    if(datagram.size() == sizeof(normal_request_t)){
        emit gotResponse(datagram);
    }else if(datagram.size() == sizeof(response_data_t)){
        emit gotImageData(datagram);
    }
}

void ClientTransfer::imgRequest(unsigned int timestamp, int seq, int width, int height, int state, int speed){
    QByteArray request;
    request.resize(sizeof(normal_request_t));

    requestInfo(request.data())->type = IMAGE_REQUEST;
    setRequestField(request.data(), IMAGE_TIMESTAMP, timestamp);
    setRequestField(request.data(), IMAGE_SEQ, seq);
    setRequestField(request.data(), IMAGE_WIDTH, width);
    setRequestField(request.data(), IMAGE_HEIGHT, height);
    setRequestField(request.data(), IMAGE_TRAN_SWITCH, state);
    setRequestField(request.data(), IMAGE_TRAN_SPEED, speed);
    this->packRequest(request);
    this->sendInfoRequest(request);
}

void ClientTransfer::trackRequest(int timestamp, int x1, int y1, int x2, int y2){
    QByteArray request;
    request.resize(sizeof(normal_request_t));
    requestInfo(request.data())->type = TRACK_REQUEST;
    setRequestField(request.data(), TRACK_TIMESTAMP, timestamp);
    setRequestField(request.data(), TRACK_PT_X1, x1);
    setRequestField(request.data(), TRACK_PT_X2, x2);
    setRequestField(request.data(), TRACK_PT_Y1, y1);
    setRequestField(request.data(), TRACK_PT_Y2, y2);
    this->packRequest(request);
    this->sendInfoRequest(request);
}

void ClientTransfer::ptzRequest(int x, int y, int z){
    QByteArray request;
    request.resize(sizeof(normal_request_t));
    requestInfo(request.data())->type = PTZ_REQUEST;
    setRequestField(request.data(), PTZ_X, x);
    setRequestField(request.data(), PTZ_Y, y);
    setRequestField(request.data(), PTZ_Z, z);
    this->packRequest(request);
    requestInfo(request.data())->action = SET_GET;
    this->sendInfoRequest(request);

}

void ClientTransfer::cameraRequest(int b, int c, int h, int s, int r){
    QByteArray request;
    request.resize(sizeof(normal_request_t));
    requestInfo(request.data())->type = CAMERA_REQUEST;
    setRequestField(request.data(), CAMERA_FOCUS, 0);
    setRequestField(request.data(), CAMERA_BRIGHTNESS, b);
    setRequestField(request.data(), CAMERA_CONTRAST, c);
    setRequestField(request.data(), CAMERA_HUE, h);
    setRequestField(request.data(), CAMERA_SATURATION, s);
    setRequestField(request.data(), CAMERA_RECORD, r);
    this->packRequest(request);
    requestInfo(request.data())->action = SET_GET;
    this->sendInfoRequest(request);
}

void ClientTransfer::setServer(QHostAddress addr, quint16 sync_port, quint16 info_port, quint16 data_port){
    this->m_server_addr = addr;
    this->m_server_sync_port = sync_port;
    this->m_server_info_port = info_port;
    this->m_server_data_port = data_port;
    this->m_timer.setInterval(1000);
    this->m_timer.start();
}
